# src/core/web/strategies.py
import time
import re
from typing import List
from .interfaces import IWebScrapingStrategy
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from webdriver_manager.chrome import ChromeDriverManager

class UcampusStrategy(IWebScrapingStrategy):
    """
    针对U校园（unipus.cn）的题目抓取策略。
    采用“组装”逻辑：先找到所有文本片段，再根据内容（如“1.”）将它们重新组装成完整的题目。
    """
    
    # 1. 定位到包含所有题目信息的总区域
    QUESTIONS_AREA_SELECTOR = "div.questions--questionDefault-2XLzl"
    
    # 2. 在总区域内，找到所有可能包含文本的“零件”
    TEXT_PART_SELECTOR = "div.html-view"
    
    def scrape_questions(self, url: str) -> List[str]:
        print("正在启动浏览器...")
        service = ChromeService(ChromeDriverManager().install())
        driver = webdriver.Chrome(service=service)
        driver.maximize_window()
        
        final_questions = []
        try:
            driver.get(url)
            print("="*50)
            print("浏览器已打开。请在浏览器中手动完成登录操作。")
            print("登录成功并【完全加载】题目页面后，请在本控制台按 Enter 键继续...")
            print("="*50)
            input()

            print("用户确认，开始执行“组装”策略...")
            wait = WebDriverWait(driver, 30)
            
            # 步骤1: 定位到包含所有题目的总区域
            print(f">>> 正在定位总区域: '{self.QUESTIONS_AREA_SELECTOR}'")
            questions_area = wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, self.QUESTIONS_AREA_SELECTOR))
            )

            # 步骤2: 从总区域中获取所有可能的文本“零件”
            print(f">>> 正在从总区域中提取所有文本零件: '{self.TEXT_PART_SELECTOR}'")
            text_parts = questions_area.find_elements(By.CSS_SELECTOR, self.TEXT_PART_SELECTOR)
            
            print(f">>> 提取到 {len(text_parts)} 个文本零件，开始进行智能组装...")

            current_question_parts = []
            for part in text_parts:
                part_text = part.text.strip()
                if not part_text:
                    continue # 跳过空的零件

                # 步骤3: 判断零件是否是一个新题目的开头 (以 "数字." 开头)
                if re.match(r"^\d+\.", part_text):
                    # 如果是新题目的开头，那么先将之前收集的“零件”组装成一个完整题目
                    if current_question_parts:
                        final_questions.append("\n".join(current_question_parts))
                        print(f"      - 已组装完成一个题目: {current_question_parts[0][:30]}...")
                    
                    # 然后开始收集新题目的零件
                    current_question_parts = [part_text]
                else:
                    # 如果不是新题目的开头，就把它当作当前题目的一个部分
                    current_question_parts.append(part_text)

            # 步骤4: 不要忘记组装最后一个题目
            if current_question_parts:
                final_questions.append("\n".join(current_question_parts))
                print(f"      - 已组装完成最后一个题目: {current_question_parts[0][:30]}...")

            print(f">>> 组装完成，共得到 {len(final_questions)} 个有效题目。")

        except Exception as e:
            print(f"网页抓取过程中发生严重错误: {e}")
        finally:
            print(">>> 抓取结束，正在关闭浏览器...")
            time.sleep(2)
            driver.quit()
            
        return final_questions